package com.onlyxiahui.common.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 
 * Description 
 * <br>
 * Date 2019-04-01 10:18:21<br>
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
public class OnlyNumberUtil {

	static DecimalFormat df = new DecimalFormat("#.##");

	/**
	 * 保留2位小数，当没小数时取整数
	 *
	 * @param number
	 * @return String
	 */
	public static String format(double number) {
		return df.format(number);
	}

	public static String format(double number, String format) {
		return new DecimalFormat(format).format(number);
	}

	/**
	 * 判断字符串是不是数字类型
	 *
	 * @param value
	 * @return boolean
	 */
	public static boolean isNumber(String value) {

		if (OnlyStringUtil.isBlank(value)) {
			return false;
		}
		char[] chars = value.toCharArray();
		int sz = chars.length;
		boolean hasExp = false;
		boolean hasDecPoint = false;
		boolean allowSigns = false;
		boolean foundDigit = false;
		// deal with any possible sign up front
		int start = (chars[0] == '-') ? 1 : 0;
		if (sz > start + 1) {
			if (chars[start] == '0' && chars[start + 1] == 'x') {
				int i = start + 2;
				if (i == sz) {
					return false; // str == "0x"
				}
				// checking hex (it can't be anything else)
				for (; i < chars.length; i++) {
					if ((chars[i] < '0' || chars[i] > '9')
							&& (chars[i] < 'a' || chars[i] > 'f')
							&& (chars[i] < 'A' || chars[i] > 'F')) {
						return false;
					}
				}
				return true;
			}
		}
		sz--; // don't want to loop to the last char, check it afterwords
		// for type qualifiers
		int i = start;
		// loop to the next to last char or to the last char if we need another
		// digit to
		// make a valid number (e.g. chars[0..5] = "1234E")
		while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
			if (chars[i] >= '0' && chars[i] <= '9') {
				foundDigit = true;
				allowSigns = false;

			} else if (chars[i] == '.') {
				if (hasDecPoint || hasExp) {
					// two decimal points or dec in exponent
					return false;
				}
				hasDecPoint = true;
			} else if (chars[i] == 'e' || chars[i] == 'E') {
				// we've already taken care of hex.
				if (hasExp) {
					// two E's
					return false;
				}
				if (!foundDigit) {
					return false;
				}
				hasExp = true;
				allowSigns = true;
			} else if (chars[i] == '+' || chars[i] == '-') {
				if (!allowSigns) {
					return false;
				}
				allowSigns = false;
				foundDigit = false; // we need a digit after the E
			} else {
				return false;
			}
			i++;
		}
		if (i < chars.length) {
			if (chars[i] >= '0' && chars[i] <= '9') {
				// no type qualifier, OK
				return true;
			}
			if (chars[i] == 'e' || chars[i] == 'E') {
				// can't have an E at the last byte
				return false;
			}
			if (!allowSigns
					&& (chars[i] == 'd'
							|| chars[i] == 'D'
							|| chars[i] == 'f'
							|| chars[i] == 'F')) {
				return foundDigit;
			}
			if (chars[i] == 'l' || chars[i] == 'L') {
				// not allowing L with an exponent
				return foundDigit && !hasExp;
			}
			// last character is illegal
			return false;
		}
		// allowSigns is true iff the val ends in 'E'
		// found digit it to make sure weird stuff like '.' and '1E-' doesn't
		// pass
		return !allowSigns && foundDigit;

	}

	/**
	 * 判断字符串是不是整型
	 *
	 * @param value
	 * @return boolean
	 */
	public static boolean isInteger(String value) {
		try {
			if (OnlyStringUtil.isBlank(value)) {
				return false;
			}
			for (int index = 0; index < value.length(); index++) {
				if (48 > (int) value.charAt(index) || (int) value.charAt(index) > 57) {
					return false;
				}
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * 返回四舍五入后精确小数点2位
	 *
	 * @return double
	 */
	public static double roundHalfUpDouble(double money) {
		BigDecimal b = new BigDecimal(money);
		double d2 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		return d2;
	}

	private static final int DEF_DIV_SCALE = 10;

	/**
	 * 两个Double数相加
	 *
	 * @param v1
	 * @param v2
	 * @return double
	 */
	public static double add(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}

	/**
	 * 两个Double数相减
	 *
	 * @param v1
	 * @param v2
	 * @return double
	 */
	public static double subtract(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 两个Double数相乘
	 *
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static double multiply(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 两个Double数相除
	 *
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static double divide(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();

	}

	/**
	 * 两个Double数相除，并保留scale位小数
	 *
	 * @param v1
	 * @param v2
	 * @param scale
	 * @return double
	 */
	public static double divide(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 返回两个数里比较大的值
	 *
	 * @param v1
	 * @param v2
	 * @return double
	 */
	public static double max(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.max(b2).doubleValue();
	}

	/**
	 * 返回两个数里比较小的值
	 *
	 * @param v1
	 * @param v2
	 * @return double
	 */
	public static double min(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.min(b2).doubleValue();
	}

	/**
	 * 对double数据取精度，例输入1.666666，3，返回1.667
	 *
	 * @param v
	 * @param scale
	 * @return double
	 */
	public static double round(double v, int scale) {
		BigDecimal b = new BigDecimal(Double.toString(v));
		b = b.setScale(scale, BigDecimal.ROUND_HALF_UP);
		return b.doubleValue();
	}

	/**
	 * 取余数，输入55.5，40，2，返回15.5
	 *
	 * @param v1
	 * @param v2
	 * @param scale
	 * @return double
	 */
	public static double remainder(double v1, double v2, int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 字符串转换为double,如果字符串为空则返回默认值
	 *
	 * @param text
	 * @param defaultValue
	 * @return double
	 */
	public static double parseDouble(String text, double defaultValue) {
		if (OnlyStringUtil.isBlank(text)) {
			return defaultValue;
		}
		text = OnlyStringUtil.trim(text);
		return Double.parseDouble(text);
	}

	/**
	 * 字符串转换为float,如果字符串为空则返回默认值
	 *
	 * @param text
	 * @param defaultValue
	 * @return float
	 */
	public static float parseFloat(String text, float defaultValue) {
		if (OnlyStringUtil.isBlank(text)) {
			return defaultValue;
		}
		text = OnlyStringUtil.trim(text);
		return Float.parseFloat(text);
	}

	/**
	 * 字符串转换为int,如果字符串为空则返回默认值
	 *
	 * @param text
	 * @param defaultValue
	 * @return int
	 */
	public static int parseIntger(String text, int defaultValue) {
		if (OnlyStringUtil.isBlank(text)) {
			return defaultValue;
		}
		text = OnlyStringUtil.trim(text);
		return Integer.parseInt(text);
	}

	/**
	 * 字符串转换为long,如果字符串为空则返回默认值
	 *
	 * @param text
	 * @param defaultValue
	 * @return long
	 */
	public static long parseLong(String text, long defaultValue) {
		if (OnlyStringUtil.isBlank(text)) {
			return defaultValue;
		}
		text = OnlyStringUtil.trim(text);
		return Long.parseLong(text);
	}
}
